package com.yykj.hospital.server.service.account.impl;

import com.yykj.common.enums.ResultEnums;
import com.yykj.common.exception.NormalException;
import com.yykj.common.service.RedisService;
import com.yykj.hospital.server.enums.AccountType;
import com.yykj.hospital.server.model.entity.account.AccountSystem;
import com.yykj.hospital.server.model.entity.account.AccountSystemLog;
import com.yykj.hospital.server.model.repository.account.AccountSystemLogRepository;
import com.yykj.hospital.server.model.repository.account.AccountSystemRepository;
import com.yykj.hospital.server.service.account.SystemAccountService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;

@Service
@Slf4j
public class SystemAccountServiceImpl implements SystemAccountService {
    @Override
    public AccountSystemLog income(AccountSystemLog accountLog) {
        String key = "system_account_lock_" + accountLog.getHospitalId() + "_" + accountLog.getAccountType();
        String value = redisService.getKeyLock(key);
        AccountSystem accountSystem = getSystemAccount(accountLog.getHospitalId(), accountLog.getAccountType());
        accountSystem.setBalance(accountSystem.getBalance().add(accountLog.getPrice()));
        accountSystemRepository.save(accountSystem);
        accountLog.setBalance(accountSystem.getBalance());
        accountLog = accountSystemLogRepository.save(accountLog);
        redisService.unlock(key,value);
        return accountLog;
    }

    @Override
    public AccountSystemLog expend(AccountSystemLog log) {
        String key = "system_account_lock_" + log.getHospitalId() + "_" + log.getAccountType();
        String value = redisService.getKeyLock(key);
        AccountSystem accountSystem = getSystemAccount(log.getHospitalId(), log.getAccountType());
        if (accountSystem.getBalance().compareTo(log.getPrice()) < 0) {
            throw new NormalException(ResultEnums.NOT_ENOUGH_BALANCE);
        }
        accountSystem.setBalance(accountSystem.getBalance().subtract(log.getPrice()));
        accountSystemRepository.save(accountSystem);

        log.setBalance(accountSystem.getBalance());
        log = accountSystemLogRepository.save(log);
        redisService.unlock(key,value);
        return log;
    }

    private AccountSystem getSystemAccount(Integer hospitalId, AccountType accountType) {
        AccountSystem accountSystem = accountSystemRepository.findFirstByHospitalIdAndAccountType(hospitalId, accountType);
        if (accountSystem == null) {
            accountSystem = new AccountSystem();
            accountSystem.setHospitalId(hospitalId);
            accountSystem.setBalance(BigDecimal.ZERO);
            accountSystem.setAccountType(accountType);
        }
        return accountSystem;
    }

    private AccountSystemRepository accountSystemRepository;
    private AccountSystemLogRepository accountSystemLogRepository;

    private RedisService redisService;

    @Autowired
    public void setSystemAccountRepository(AccountSystemRepository accountSystemRepository) {
        this.accountSystemRepository = accountSystemRepository;
    }

    @Autowired
    public void setSystemAccountLogRepository(AccountSystemLogRepository accountSystemLogRepository) {
        this.accountSystemLogRepository = accountSystemLogRepository;
    }
    @Autowired
    public void setRedisService(RedisService redisService) {
        this.redisService = redisService;
    }
}
